#include "comqueue.h"

/**
 * 包含顺序栈和链式栈的类 
 **/
extern func_SeqStack fun_SeqStack;
extern func_LinkStack fun_LinkStack;

/**
 * 功 能：
 *      创建一个队列
 * 参 数：
 *      无
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
ComQueue *ComQueue_Create(int capacity)
{
    TComQueue *queue = (TComQueue *)malloc(sizeof(TComQueue));
    if (queue == NULL)
        return NULL;

    queue->enStack = fun_SeqStack.create(capacity);
    queue->deStack = fun_LinkStack.create();
    if (queue->enStack == NULL || queue->deStack == NULL)
    {
        fun_SeqStack.destroy(queue->enStack);
        fun_LinkStack.destroy(queue->deStack);

        free(queue);
        return NULL;
    }

    return queue;
}

/**
 * 功 能：
 *      清空一个队列
 * 参 数：
 *      queue：要操作的队列
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int ComQueue_Clear(ComQueue *queue)
{
    int ret = -1;
    TComQueue *temp = (TComQueue *)queue;
    if (temp == NULL)
        return -1;

    ret = fun_SeqStack.clear(temp->enStack);
    if (ret != 0)
        return ret;

    ret = fun_LinkStack.clear(temp->deStack);
    if (ret != 0)
        return ret;

    return ret;
}

/**
 * 功 能：
 *      销毁一个队列
 * 参 数：
 *      queue：要操作的队列
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int ComQueue_Destroy(ComQueue *queue)
{
    int ret = ComQueue_Clear(queue);
    if (queue != NULL)
        free(queue);

    return ret;
}

/**
 * 功 能：
 *      获取队列的长度
 * 参 数：
 *      queue：要操作的队列
 * 返回值：
 *      成功：队列的长度
 *      失败：-1
 **/
int ComQueue_Length(ComQueue *queue)
{
    TComQueue *tqueue = (TComQueue *)queue;
    if (tqueue == NULL)
        return -1;

    int len = fun_SeqStack.length(tqueue->enStack) +
              fun_LinkStack.length(tqueue->deStack);

    return len;
}

/**
 * 功 能：
 *      插入元素，压队列
 * 参 数：
 *      queue：要操作的队列
 *      item : 要插入的元素，队列的业务节点
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int ComQueue_Append(ComQueue *queue, ComQueueNode *item)
{
    TComQueue *tqueue = (TComQueue *)queue;
    if (tqueue == NULL)
        return -1;

    int ret = fun_SeqStack.push(tqueue->enStack, (SeqStackNode *)item);

    return ret;
}

/**
 * 功 能：
 *      获取队列头的元素
 * 参 数：
 *      queue：要操作的队列
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
ComQueueNode *ComQueue_Header(ComQueue *queue)
{
    TComQueue *tqueue = (TComQueue *)queue;
    if (tqueue == NULL)
        return NULL;

    ComQueueNode *ret = NULL;
    if (fun_LinkStack.length(tqueue->deStack) == 0)
    {
        while (fun_SeqStack.length(tqueue->enStack) > 0)
        {
            fun_LinkStack.push(tqueue->deStack,
                               (LinkStackNode *)fun_SeqStack.pop(
                                   tqueue->enStack));
        }
    }

    ret = fun_LinkStack.top(tqueue->deStack);

    return ret;
}

/**
 * 功 能：
 *      弹出队列元素
 * 参 数：
 *      queue：要操作的队列
 * 返回值：
 *      成功：删除后的元素
 *      失败：NULL
 **/
ComQueueNode *ComQueue_Subtract(ComQueue *queue)
{
    TComQueue *tqueue = (TComQueue *)queue;
    if (tqueue == NULL)
        return NULL;

    ComQueueNode *ret = NULL;
    if (fun_LinkStack.length(tqueue->deStack) == 0)
    {
        while (fun_SeqStack.length(tqueue->enStack) > 0)
        {
            fun_LinkStack.push(tqueue->deStack,
                               fun_SeqStack.pop(
                                   tqueue->enStack));
        }
    }

    ret = fun_LinkStack.pop(tqueue->deStack);

    return ret;
}

/**
 * 功 能：
 *      获取队列的最大容量
 * 参 数：
 *      Queue：要操作的队列
 * 返回值：
 *      成功：队列得容量
 *      失败：-1
 **/
int ComQueue_Capacity(ComQueue *queue)
{
    TComQueue *tqueue = (TComQueue *)queue;
    return fun_SeqStack.capacity((SeqStack *)tqueue->enStack);
}

func_ComQueue fun_ComQueue = {
    ComQueue_Create,
    ComQueue_Destroy,
    ComQueue_Clear,
    ComQueue_Length,
    ComQueue_Append,
    ComQueue_Header,
    ComQueue_Subtract,
    ComQueue_Capacity};
